classdef TestDotsTheSwitchboard < dotsTestCase
    
    properties
        theBoard;
    end
    
    methods
        function self = TestDotsTheSwitchboard(name)
            self = self@dotsTestCase(name);
        end
        
        function setUp(self)
            self.setUp@dotsTestCase;
            dotsTheSwitchboard.reset();
            self.theBoard = dotsTheSwitchboard.theObject;
        end
        
        function tearDown(self)
            dotsTheSwitchboard.reset();
            self.tearDown@dotsTestCase;
        end
        
        function testShareUnshareObjectProperties(self)
            object = dotsAllManagedObjectsTestable;
            props = {'testProperty', 'returnValue'};
            prop = props{1};
            
            initialShared = dotsTheSwitchboard.getSharedProperties;
            assertEqual(sum(strcmp(initialShared, prop)), 0, ...
                'initially should not be sharing the given property')
            
            dotsTheSwitchboard.sharePropertyOfObject(prop, object);
            addedShared = dotsTheSwitchboard.getSharedProperties;
            assertEqual(sum(strcmp(addedShared, prop)), 1, ...
                'should be sharing the given property')
            addedObject = dotsTheSwitchboard.getObjectsSharingProperty(prop);
            assertEqual(length(addedObject), 1, ...
                'one object should be sharing the given property')
            assertEqual(addedObject{1}, object, ...
                'the given object should be sharing the given property')
            
            dotsTheSwitchboard.sharePropertyOfObject(prop, object);
            readdedShared = dotsTheSwitchboard.getSharedProperties;
            assertEqual(sum(strcmp(readdedShared, prop)), 1, ...
                'should be no-op to reshare the given property')
            readdedObject = dotsTheSwitchboard.getObjectsSharingProperty(prop);
            assertEqual(length(readdedObject), 1, ...
                'still one object should be sharing the given property')
            assertEqual(readdedObject{1}, object, ...
                'the same object should be sharing the given property')
            
            dotsTheSwitchboard.unsharePropertyOfObject(prop, object);
            unaddedObject = dotsTheSwitchboard.getObjectsSharingProperty(prop);
            assertEqual(length(unaddedObject), 0, ...
                'no object should be sharing the given property')
            
            dotsTheSwitchboard.shareManyPropertiesOfObject(props, object);
            manyAddedShared = dotsTheSwitchboard.getSharedProperties;
            for ii = 1:length(props)
                prop = props{ii};
                assertEqual(sum(strcmp(manyAddedShared, prop)), 1, ...
                    'should be sharing the each given property')
                
                manyAddedObject = dotsTheSwitchboard.getObjectsSharingProperty(prop);
                assertEqual(length(addedObject), 1, ...
                    'one object should be sharing each given property')
                assertEqual(manyAddedObject{1}, object, ...
                    'the given object should be sharing each given property')
            end
            
            dotsTheSwitchboard.unshareManyPropertiesOfObject(props, object);
            manyUnaddedShared = dotsTheSwitchboard.getSharedProperties;
            for ii = 1:length(props)
                prop = props{ii};
                manyUnaddedObject = dotsTheSwitchboard.getObjectsSharingProperty(prop);
                assertEqual(length(manyUnaddedObject), 0, ...
                    'no object should be sharing each given property')
            end
        end
        
        function testGetSetSharedValue(self)
            prop = 'testProperty';
            object(1) = dotsAllManagedObjectsTestable;
            object(1).(prop) = -1;
            object(2) = dotsAllManagedObjectsTestable;
            object(2).(prop) = -2;
            
            dotsTheSwitchboard.sharePropertyOfObject(prop, object(1));
            sharedValue = dotsTheSwitchboard.getSharedPropertyValue(prop);
            assertEqual(sharedValue, object(1).(prop), ...
                'should take shared value from first object');
            
            dotsTheSwitchboard.sharePropertyOfObject(prop, object(2));
            assertEqual(sharedValue, object(1).(prop), ...
                'should not take shared value from second object');
            assertEqual(sharedValue, object(2).(prop), ...
                'should assign shared value to second object');
            
            % should assign new value to both objects
            sharedValue = -3;
            dotsTheSwitchboard.setSharedPropertyValue(prop, sharedValue);
            assertEqual(sharedValue, object(1).(prop), ...
                'should assign new shared value to first object');
            assertEqual(sharedValue, object(2).(prop), ...
                'should assign new shared value to second object');
        end
    end
end